package com.zxwl.base.action;

import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Method;
import java.sql.BatchUpdateException;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.RequestAware;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.SessionAware;
import org.springframework.expression.spel.ast.Operator;

import com.opensymphony.xwork2.ActionSupport;
import com.zxwl.base.dao.DataPage;
import com.zxwl.base.dao.Parameter;
import com.zxwl.base.dao.QueryParameter;
import com.zxwl.base.service.IBaseService;
import com.zxwl.common.type.ZxwlTypeConverter;
import com.zxwl.common.util.JsonUtil;
import com.zxwl.common.util.StringUtil;

public abstract class BaseAction<E> extends ActionSupport implements ServletRequestAware,RequestAware, SessionAware
{
	
	protected IBaseService<E> service;
	private static final long serialVersionUID = 1L;
	protected HttpServletRequest servletRequest;
	protected Map<String, Object> request;
	protected Map<String, Object> session;
	
	@SuppressWarnings("hiding")
	public <E>BaseAction()
	{
	}
	
	/**
	 * 适用于Ajax调用ACTION 回调函数中获取ACTION返回状态数据 ACTiON方法必须返回null
	 * 
	 * @param data
	 * @throws IOException
	 */
	protected void writeStringToClient(String data)
	{
		HttpServletResponse response = ServletActionContext.getResponse();
		try
		{	
			response.setContentType("text/html;charset=UTF-8");
			response.getWriter().write(data);
		} catch (IOException e)
		{
		}
	}
	protected void sendDataToClient(Object data)
	{
		sendJsonToClient(data);
	}
	protected void sendJsonToClient(Object data)
	{
		String jSon;
		if(data instanceof List)
		{
			jSon = JsonUtil.listToJson((List<?>)data);
		}
		else if(data instanceof Map)
		{
			jSon = JsonUtil.MaptoJson((Map<?,?>)data);
		}
		else
		{
			jSon = JsonUtil.beanToJson(data);
		}
		writeStringToClient(jSon);
	}
	
	@Override
	public void setSession(Map<String, Object> session)
	{
		this.session = session;
	}

	@Override
	public void setRequest(Map<String, Object> request)
	{
		this.request = request;
	}
	
	public Operator getCurrentOperator()
	{
		return (Operator)this.session.get("loginUser");
	}
	
	public String getHostIp()
	{
		return this.servletRequest.getRemoteAddr();
	}

	@Override
	public void setServletRequest(HttpServletRequest servletRequest)
	{
		this.servletRequest = servletRequest;
	}
	
	public String getAttributeValue(String name)
	{
		HttpServletRequest httpRequest = ServletActionContext.getRequest();
		if( null != httpRequest)
		{
			Object object =  httpRequest.getAttribute(name);
			if(null != object)
			{
				return object.toString();
			}
		}
		return null;
	}
	public String getParameterValue(String paraName)
	{
		HttpServletRequest httpRequest = ServletActionContext.getRequest();
		if( null != httpRequest)
		{
			return httpRequest.getParameter(paraName);
		}
		return null;
	}
	
	public void putRequestValue(String key, Object value)
	{
		this.request.put(key, value);
	}
	
	public Object getRequestValue(String key)
	{
		return this.request.get(key);
	}
	
	public boolean IsUniqueException(Exception e)
	{
		Throwable t = e.getCause();
		while( t.getCause() != null)
		{
			t = t.getCause();
		}
		if(t instanceof BatchUpdateException)
		{
			BatchUpdateException updateException = (BatchUpdateException)t;
			if(updateException.getSQLState().equals("23000"))
			{
				return true;
			}
		}
		return false;
	}
	
	public void setErrorMessage(String errorMsg)
	{
		this.putRequestValue("errorMsg", errorMsg);
	}
	/**
	 * 获得坐席电脑IP
	 * @return
	 */
	public String getClientIp()
	{
		HttpServletRequest httpRequest = ServletActionContext.getRequest();
		String ip=httpRequest.getHeader("x-forwarded-for");
		if(ip==null || ip.length()==0 || "unknown".equalsIgnoreCase(ip))
		{
		         ip=httpRequest.getHeader("Proxy-Client-IP");
		}
		if(ip==null || ip.length()==0 || "unknown".equalsIgnoreCase(ip))
		{
		           ip=httpRequest.getHeader("WL-Proxy-Client-IP");
		}
		if(ip==null || ip.length()==0 || "unknown".equalsIgnoreCase(ip))
		{
		           ip=httpRequest.getRemoteAddr();
		}
		return ip;
	}
	
	
	 
	/**
	 * 查询当前操作员是否有该权限
	 * @param actionName 权限项action名称
	 * @return boolean
	 */
	public boolean getPower(String actionName)
	{
		//Operator op = this.getCurrentOperator();
		//return op.getPower(actionName);
		return false;
	}
	
	public void sendSuccessResult(String message)
	{
		String resultData = "{\"message\":\"" + message + "\",\"result\":\"success\"}";
		this.writeStringToClient(resultData);
	}
	
	public void sendErrorResult(String message)
	{
		String resultData = "{\"message\":\"" + message + "\",\"result\":\"error\"}";
		this.writeStringToClient(resultData);
	}
	
	public QueryParameter getParameter(QueryParameter queryParameter)
	{
		if(null != queryParameter && queryParameter.size() > 0)
		{
			Set<String> names = queryParameter.findParameterNames();
			for(String name:names)
			{
				Parameter parameter = queryParameter.findParameter(name);
				if(parameter != null)
				{
					try
					{
						String value = this.getParameterValue(parameter.getName());
						if(value != null && !value.equals(""))
						{
							parameter.setValue(value);
						}
					}
					catch(Exception e)
					{
					}
				}
			}
		}
		return queryParameter;
	}
	public E getEntity()
	{
		try
		{
			ZxwlTypeConverter converter = ZxwlTypeConverter.getInstance();
			E entity = this.service.createEntity();
			PropertyDescriptor[] props  = Introspector.getBeanInfo(entity.getClass(), Object.class).getPropertyDescriptors();
			for(PropertyDescriptor prop:props)
			{
				String propName = prop.getName();
				String value = this.getParameterValue(propName);
				if(!StringUtil.isEmpty(value))
				{
					value = value.trim();
				}
				Method setter = prop.getWriteMethod();
				Class<?> classType = prop.getPropertyType();
				if(setter != null && value != null && !value.equals(""))
				{
					setter.invoke(entity, converter.convertValue(value,classType));
				}
			}
			return entity;
		}
		catch(Exception e)
		{
			return null;
		}
	}
	
	/**
	 * 查询单个实体
	 * @return
	 */
	public String query()
	{
		try
		{
			String id = this.getParameterValue("id");
			E entity = service.query(Integer.parseInt(id));
			this.sendDataToClient(entity);
		}
		catch(Exception e)
		{
			this.sendErrorResult("查询失败!");
		}
		return null;
	}
	/**
	 * 删除单个实体
	 * @return
	 */
	public String delete()
	{
		try
		{
			String id = this.getParameterValue("id");
			service.delete(Integer.parseInt(id));
			this.sendSuccessResult("删除成功!");
		}
		catch(Exception e)
		{
			this.sendErrorResult("删除失败!");
		}
		return null;
	}
	/**
	 * 保存单个实体的更新
	 * @return
	 */
	public String update()
	{
		try
		{
			E entity = (E) this.getEntity();
			// 判断是否已经更改
			if(service.isChanged(entity))
			{
				this.sendErrorResult("记录已经修改，不允许保存");
			}
			else
			{
				service.update(entity);
				this.sendSuccessResult("更新成功!");
			}
		}
		catch(Exception e)
		{
			this.sendErrorResult("更新失败!");
		}
		return null;
	}
	/**
	 * 新增单个实体
	 * @return
	 */
	public String save()
	{
		try
		{
			E entity = (E) this.getEntity();
			service.save(entity);
			this.sendSuccessResult("保存成功!");
		}
		catch(Exception e)
		{
			this.sendErrorResult("保存失败!");
		}
		return null;
	}
	/**
	 * 查询实体列表
	 * @return
	 */
	public String queryList()
	{
		try
		{
			QueryParameter queryParameter = new QueryParameter();
			fullQueryParameter(queryParameter);
			queryParameter.addIntegerParameter("pageSize");
			queryParameter.addIntegerParameter("pageNum");
			queryParameter = getParameter(queryParameter);
			DataPage<E> dataPage = new DataPage<E>();
			
			dataPage.setQueryParameter(queryParameter);
			service.queryForPage(dataPage);
			this.sendDataToClient(dataPage);
		}
		catch(Exception e)
		{
			this.sendErrorResult("查询失败!");
		}
		return null;
	}
	public abstract void setService(IBaseService<E> service);
	public abstract void fullQueryParameter(QueryParameter queryParameter);
	
	
}

